#pragma once

#include "Slot.h"

#include "InstanceSpecification.h"
#include "StructuralFeature.h"
#include "ValueSpecification.h"

namespace uml {

Slot::Slot(const QString& umlType)
    : Element(umlType) {}

void Slot::fromJson(const QJsonObject& json, QStringList& errorList) {
    if (json.isEmpty()) {
        return;
    }

    Element::fromJson(json, errorList);
    definingFeature_ = JsonSerializable::create<StructuralFeature>(json.value("definingFeature"), errorList);

    owningInstance_ = JsonSerializable::create<InstanceSpecification>(json.value("owningInstance"), errorList);

    JsonSerializable::fromJsonArray(values_, "values", json, errorList);
}

void Slot::toJson(QJsonObject& json) {
    Element::toJson(json);
    if (definingFeature_) {
        QJsonObject definingFeature_json;
        definingFeature_->toJson(definingFeature_json);
        json.insert("definingFeature", definingFeature_json);
    }
    if (owningInstance_) {
        QJsonObject owningInstance_json;
        owningInstance_->toJson(owningInstance_json);
        json.insert("owningInstance", owningInstance_json);
    }
    JsonSerializable::toJsonArray(values_, "values", json);
}

/// <summary>
/// definingFeature getter
/// The StructuralFeature that specifies the values that may be held by the Slot.
/// </summary>
shared_ptr<StructuralFeature> Slot::definingFeature() const {
    return definingFeature_;
}

/// <summary>
/// definingFeature setter
/// The StructuralFeature that specifies the values that may be held by the Slot.
/// </summary>
void Slot::setDefiningFeature(shared_ptr<StructuralFeature> value) {
    definingFeature_ = value;
}

/// <summary>
/// owningInstance getter
/// The InstanceSpecification that owns this Slot.
/// </summary>
shared_ptr<InstanceSpecification> Slot::owningInstance() const {
    return owningInstance_;
}

/// <summary>
/// owningInstance setter
/// The InstanceSpecification that owns this Slot.
/// </summary>
void Slot::setOwningInstance(shared_ptr<InstanceSpecification> value) {
    owningInstance_ = value;
}

/// <summary>
/// values getter
/// The value or values held by the Slot.
/// </summary>
vector<shared_ptr<ValueSpecification>>& Slot::values() {
    return values_;
}

} // namespace uml
